﻿using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using Architecture.DataLayer.DbAccess;
using CommonComponents.Cache;
using CommonComponents.Configuration;
using CommonComponents.ExceptionHandling;
using LASLogic.BusinessLayer.DataModel;
using LASLogic.BusinessLayer.Utilities;

namespace LASLogic.DataLayer.Implementor
{
    /// <summary>
    /// Clase que maneja los accesos a la base de datos de las operaciones relativas a la empresa
    /// </summary>
    public class AccountDataManager
    {
        /// <summary>
        /// Se utiliza para todos los métodos que no son orientados a usuarios
        /// </summary>
        private readonly CacheManager _cacheManager;

        /// <summary>
        /// Metodo que permite añadir una nueva cuenta a la base de datos
        /// </summary>
        /// <param name="code">Código de la cuenta, consta de 15 caractéres alfanuméricos</param>
        /// <param name="name">Nombre de la cuenta</param>
        /// <param name="foreignName">Nombre de la cuenta en otro idioma</param>
        /// <param name="parentId">Identificador de la cuenta padre</param>
        /// <param name="currencyId">Identificador de la moneda</param>
        /// <param name="accountCatalog">Identificador del catálogo de cuentas</param>
        /// <returns>Booleano indicando el estado de la inserción</returns>
        public bool InsertNewAccount(string code, string name, string foreignName, int parentId, int currencyId,
                                     int accountCatalog)
        {
            try
            {
                AppConfigReader appConfig = AppConfigReader.GetInstance();
                string spName = appConfig.GetProperty(Constants.SP_NAME_INSERT_ACCOUNT);
                var parameters = new SqlParameter[6];
                parameters[0] = new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_INSERT_ACCOUNT_CODE), code);
                parameters[1] = new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_INSERT_ACCOUNT_NAME), name);
                parameters[2] = new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_INSERT_ACCOUNT_FOREIGN_NAME),
                                                 foreignName);
                parameters[3] = new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_INSERT_ACCOUNT_PARENT_ID),
                                                 parentId);
                parameters[4] = new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_INSERT_ACCOUNT_CURRENCY_ID),
                                                 currencyId);
                parameters[5] =
                    new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_INSERT_ACCOUNT_ACCOUNT_CATALOG),
                                     accountCatalog);
                var dataHelper = new SqlDataHelper(appConfig.GetConnectionString(Constants.DB_CONN));
                return GetResult(dataHelper.ExecuteStoredProcedure(spName, parameters), dataHelper);
            }
            catch (Exception ex)
            {
                ExceptionHandlingManager.ManageException(ex, ExceptionHandlingManager.ExceptionPolicyType.DataLayer);
                return false;
            }
        }


        /// <summary>
        /// Metodo que permite cambiar el estado de una cuenta
        /// </summary>
        /// <param name="accountId">Id de la cuenta</param>
        /// <param name="status">Nuevo estado de la cuenta</param>
        public bool ChangeAccountStatus(int accountId, string status)
        {
            try
            {
                AppConfigReader appConfig = AppConfigReader.GetInstance();
                string spName = appConfig.GetProperty(Constants.SP_NAME_CHANGE_ACCOUNT_STATUS);
                var parameters = new SqlParameter[2];
                parameters[0] = new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_CHANGE_ACCOUNT_STATUS_ACCOUNT_ID), accountId);
                parameters[1] = new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_CHANGE_ACCOUNT_STATUS_ACCOUNT_STATUS), status);
                var dataHelper = new SqlDataHelper(appConfig.GetConnectionString(Constants.DB_CONN));
                return GetResult(dataHelper.ExecuteStoredProcedure(spName, parameters), dataHelper);
            }
            catch (Exception ex)
            {
                ExceptionHandlingManager.ManageException(ex, ExceptionHandlingManager.ExceptionPolicyType.DataLayer);
                return false;
            }
        }


        /// <summary>
        /// Permite borrar una cuenta del catálogo de cuentas
        /// </summary>
        /// <param name="accountId">Identificador de la cuenta a borrar</param>
        /// <returns>Booleano indicando el estado del borrado</returns>
        public bool EraseAccount(int accountId)
        {
            try
            {
                AppConfigReader appConfig = AppConfigReader.GetInstance();
                string spName = appConfig.GetProperty(Constants.SP_NAME_ERASE_ACCOUNT);
                var parameters = new SqlParameter[1];
                parameters[0] = new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_ERASE_ACCOUNT_ACCOUNT_ID),
                                                 accountId);
                var dataHelper = new SqlDataHelper(appConfig.GetConnectionString(Constants.DB_CONN));
                return GetResult(dataHelper.ExecuteStoredProcedure(spName, parameters), dataHelper);
            }
            catch (Exception ex)
            {
                ExceptionHandlingManager.ManageException(ex, ExceptionHandlingManager.ExceptionPolicyType.DataLayer);
                return false;
            }
        }

        /// <summary>
        /// Permite obtener el catalogo de cuentas de la base de datos ( Se puede mejorar pero no hay tiempo)
        /// </summary>
        /// <param name="companyId">Identificador de la compañia</param>
        /// <returns>Catalogo de cuentas de una compañia</returns>
        public AccountCatalog GetAccountingCatalog(int companyId)
        {
            try
            {
                AppConfigReader appConfig = AppConfigReader.GetInstance();
                string spName = appConfig.GetProperty(Constants.SP_NAME_GET_ACCOUNTING_CATALOG);
                var parameters = new SqlParameter[1];
                parameters[0] =
                    new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_GET_ACCOUNTING_CATALOG_COMPANY_ID),
                                     companyId);
                var dataHelper = new SqlDataHelper(appConfig.GetConnectionString(Constants.DB_CONN));
                SqlDataReader result = dataHelper.ExecuteStoredProcedure(spName, parameters);
                var accountCatalog = new AccountCatalog { Accounts = new List<Account>() };
                var accounts = new List<Account>();
                while (result.Read())
                {
                    if (accountCatalog.AccountCatalogId == 0)
                        accountCatalog.AccountCatalogId =
                            (int)result[appConfig.GetProperty(Constants.SP_OUTPUT_GET_ACCOUNTING_CATALOG_CATALOG_ID)];
                    var accountId =
                        (int)result[appConfig.GetProperty(Constants.SP_OUTPUT_GET_ACCOUNTING_CATALOG_ACCOUNT_ID)];
                    var accountCode =
                        (string)result[appConfig.GetProperty(Constants.SP_OUTPUT_GET_ACCOUNTING_CATALOG_ACCOUNT_CODE)];
                    var accountName =
                        (string)result[appConfig.GetProperty(Constants.SP_OUTPUT_GET_ACCOUNTING_CATALOG_ACCOUNT_NAME)];
                    var foreignName =
                        (string)
                        result[appConfig.GetProperty(Constants.SP_OUTPUT_GET_ACCOUNTING_CATALOG_ACCOUNT_FOREIGN_NAME)];
                    object identificadorCuenta =
                        result[appConfig.GetProperty(Constants.SP_OUTPUT_GET_ACCOUNTING_CATALOG_ACCOUNT_PARENT_ID)];
                    int parentId = 0;
                    if (identificadorCuenta is int)
                    {
                        parentId = (int)identificadorCuenta;
                    }
                    Account parentAccount = accounts.Find(e => e.AccountId == parentId);
                    var accountType =
                        (string)result[appConfig.GetProperty(Constants.SP_OUTPUT_GET_ACCOUNTING_CATALOG_ACCOUNT_TYPE)];
                    var accountStatus =
                        (string)
                        result[appConfig.GetProperty(Constants.SP_OUTPUT_GET_ACCOUNTING_CATALOG_ACCOUNT_STATUS)];
                    int accountLevel =
                        int.Parse(
                            (string)
                            result[appConfig.GetProperty(Constants.SP_OUTPUT_GET_ACCOUNTING_CATALOG_ACCOUNT_LEVEL)]);
                    int currencyId =
                        Convert.ToInt32(
                            (byte)result[appConfig.GetProperty(Constants.SP_OUTPUT_GET_ACCOUNTING_CATALOG_CURRENCY_ID)]);
                    var currencyName =
                        (string)result[appConfig.GetProperty(Constants.SP_OUTPUT_GET_ACCOUNTING_CATALOG_CURRENCY_NAME)];
                    var currencyMnemonic =
                        (string)
                        result[appConfig.GetProperty(Constants.SP_OUTPUT_GET_ACCOUNTING_CATALOG_CURRENCY_MNEMONIC)];
                    var localBalance =
                        (Decimal)
                        result[appConfig.GetProperty(Constants.SP_OUTPUT_GET_ACCOUNTING_CATALOG_ACCOUNT_BALANCE_LOCAL)];
                    var systemBalance =
                        (Decimal)
                        result[appConfig.GetProperty(Constants.SP_OUTPUT_GET_ACCOUNTING_CATALOG_ACCOUNT_BALANCE_SYSTEM)];
                    var currency = new Currency(currencyId, currencyName, currencyMnemonic,"");
                    var account = new Account(accountId, accountName, accountCode, foreignName, accountType,
                                              accountStatus, companyId, accountLevel, parentId, parentAccount,
                                              new List<Account>(), currency,
                                              localBalance,
                                              systemBalance, accountCatalog.AccountCatalogId);
                    accounts.Add(account);
                    if (parentId == 0)
                    {
                        accountCatalog.Accounts.Add(account);
                    }
                    else
                    {
                        parentAccount.Children.Add(account);
                    }
                }
                dataHelper.CloseReader();
                return accountCatalog;
            }
            catch (Exception ex)
            {
                ExceptionHandlingManager.ManageException(ex, ExceptionHandlingManager.ExceptionPolicyType.DataLayer);
                return null;
            }
        }


        /// <summary>
        /// Permite insertar el catalogo de cuentas de una compañia
        /// </summary>
        /// <param name="companyId">Identificador de la compañia la cual se quiere insertar el catálogo</param>
        /// <returns>El Id del catalogo contable</returns>
        public int InsertAccountingCatalog(int companyId)
        {
            try
            {
                AppConfigReader appConfig = AppConfigReader.GetInstance();
                string spName = appConfig.GetProperty(Constants.SP_NAME_INSERT_ACCOUNTING_CATALOG);
                var parameters = new SqlParameter[1];
                parameters[0] =
                    new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_INSERT_ACCOUNTING_CATALOG_COMPANY_ID),
                                     companyId);
                var dataHelper = new SqlDataHelper(appConfig.GetConnectionString(Constants.DB_CONN));
                SqlDataReader result = dataHelper.ExecuteStoredProcedure(spName, parameters);

                var res = -1;
                if (result.Read())
                {
                    res = (int)
                          result[
                              AppConfigReader.GetInstance().GetProperty(
                                  Constants.SP_OUTPUT_INSERT_ACCOUNTING_CATALOG_CATALOG_ID)];
                }

                dataHelper.CloseConnection();
                return res;
            }
            catch (Exception ex)
            {
                ExceptionHandlingManager.ManageException(ex, ExceptionHandlingManager.ExceptionPolicyType.DataLayer);
                return -1;
            }
        }

        /// <summary>
        /// Permite insertar un nuevo período de tiempo para una tasa de cambio
        /// </summary>
        /// <param name="companyId">Identificador de la compañia la cual se quiere insertar el catálogo</param>
        /// <param name="periodType">Tipo de periodo a insertar, mensual o trimestral</param>
        /// <param name="description"></param>
        /// <returns>El id del catalogo contable</returns>
        public bool InsertAccountingPeriod(int companyId, string periodType, string description)
        {
            try
            {
                AppConfigReader appConfig = AppConfigReader.GetInstance();
                string spName = appConfig.GetProperty(Constants.SP_NAME_INSERT_ACCOUNTING_PERIOD);
                var parameters = new SqlParameter[3];
                parameters[0] =
                    new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_INSERT_ACCOUNTING_PERIOD_COMPANY_ID),
                                     companyId);
                parameters[1] =
                    new SqlParameter(appConfig.GetProperty(Constants.SP_OUTPUT_INSERT_ACCOUNTING_PERIOD_PERIOD_TYPE),
                                     periodType);
                parameters[2] =
                    new SqlParameter(appConfig.GetProperty(Constants.SP_OUTPUT_INSERT_ACCOUNTING_PERIOD_DESCRIPTION),
                                     description);
                var dataHelper = new SqlDataHelper(appConfig.GetConnectionString(Constants.DB_CONN));
                return GetResult(dataHelper.ExecuteStoredProcedure(spName, parameters), dataHelper);
            }
            catch (Exception ex)
            {
                ExceptionHandlingManager.ManageException(ex, ExceptionHandlingManager.ExceptionPolicyType.DataLayer);
                return false;
            }
        }

        /// <summary>
        /// Permite obtener todas las monedas de la base de datos
        /// </summary>
        /// <returns>Lista de monedas de la base de datos</returns>
        public List<Currency> GetCurrencies()
        {
            try
            {
                AppConfigReader appConfig = AppConfigReader.GetInstance();
                string spName = appConfig.GetProperty(Constants.SP_NAME_GET_CURRENCIES);
                var parameters = new SqlParameter[0];
                var dataHelper = new SqlDataHelper(appConfig.GetConnectionString(Constants.DB_CONN));
                SqlDataReader result = dataHelper.ExecuteStoredProcedure(spName, parameters);
                var currencies = new List<Currency>();
                while (result.Read())
                {
                    var currencyId = Convert.ToInt32((byte)result[appConfig.GetProperty(Constants.SP_OUTPUT_GET_CURRENCIES_CURRENCY_ID)]);
                    var currencyName =
                        (string)result[appConfig.GetProperty(Constants.SP_OUTPUT_GET_CURRENCIES_CURRENCY_NAME)];
                    var currencyMnemonic =
                        (string)result[appConfig.GetProperty(Constants.SP_OUTPUT_GET_CURRENCIES_CURRENCY_MNEMONIC)];
                    var currencySymbol = (string)result[appConfig.GetProperty(Constants.SP_OUTPUT_GET_CURRENCIES_CURRENCY_SYMBOL)];
                    currencies.Add(new Currency(currencyId, currencyName, currencyMnemonic,currencySymbol));
                }
                dataHelper.CloseReader();
                return currencies;
            }
            catch (Exception ex)
            {
                ExceptionHandlingManager.ManageException(ex, ExceptionHandlingManager.ExceptionPolicyType.DataLayer);
                return null;
            }
        }


        /// <summary>
        /// Permite insertar un nuevo período de tiempo para una tasa de cambio
        /// </summary>
        /// <param name="companyId">Identificador de la compañia la cual se quiere insertar el catálogo</param>
        /// <param name="currencyIdDestiny">Identificador de la moneda correspondiente a la tasa de cambio</param>
        /// <param name="startDate">Fecha inicial en la que estará vigente el tipo de cambio</param>
        /// <param name="finishDate">Fecha final en la que estará vigente el tipo de cambio</param>
        /// <param name="exchangeRate">Valor del tipo de cambio</param>
        /// <param name="currencyIdBegining"></param>
        /// <returns>El id del catalogo contable</returns>
        public bool InsertExchangeRate(int companyId, int currencyIdBegining, int currencyIdDestiny, DateTime startDate, DateTime finishDate,
                                      decimal exchangeRate)
        {
            try
            {
                AppConfigReader appConfig = AppConfigReader.GetInstance();
                string spName = appConfig.GetProperty(Constants.SP_NAME_INSERT_EXCHANGE_RATE);
                var parameters = new SqlParameter[6];
                parameters[0] =
                    new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_INSERT_EXCHANGE_RATE_COMPANY_ID),
                                     companyId);
                parameters[1] =
                    new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_INSERT_EXCHANGE_RATE_CURRENCY_ID_BEGINING),
                                     currencyIdBegining);
                parameters[2] =
                    new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_INSERT_EXCHANGE_RATE_CURRENCY_ID_DESTINY),
                                     currencyIdDestiny);
                parameters[3] =
                    new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_INSERT_EXCHANGE_RATE_START_DATE),
                                     startDate);
                parameters[4] =
                    new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_INSERT_EXCHANGE_RATE_FINISH_DATE),
                                     finishDate);
                parameters[5] =
                    new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_INSERT_EXCHANGE_RATE_EXCHANGE_RATE),
                                     exchangeRate);
                var dataHelper = new SqlDataHelper(appConfig.GetConnectionString(Constants.DB_CONN));
                return GetResult(dataHelper.ExecuteStoredProcedure(spName, parameters), dataHelper);
            }
            catch (Exception ex)
            {
                ExceptionHandlingManager.ManageException(ex, ExceptionHandlingManager.ExceptionPolicyType.DataLayer);
                return false;
            }
        }

        /// <summary>
        /// Permite obtener los estados para un pais
        /// </summary>
        /// <param name="companyId">Identificador de la compania</param>
        /// <param name="currencyIdBegining">Nombre de la moneda que se quiere obtener el tipo de cambio</param>
        /// <param name="currencyIdDestiny">Nombre de la moneda destino que se quiere obtener el tipo de cambio</param>
        /// <param name="fechaActual">Fecha que se quiere averiguar el tipo de cambio de las monedas</param>
        /// <returns>Retorna una lista de estados</returns>
        public decimal GetExchangeRate(int companyId, int currencyIdBegining, int currencyIdDestiny, DateTime fechaActual)
        {
            try
            {
                //string key = Constants.SP_NAME_INSERT_EXCHANGE_RATE + currencyIdBegining + currencyIdDestiny + fechaActual;
                /*if (_cacheManager.Contains(key))
                    return (decimal)_cacheManager.Get(key);*/

                AppConfigReader appConfig = AppConfigReader.GetInstance();
                string spName = appConfig.GetProperty(Constants.SP_NAME_GET_EXCHANGE_RATE);
                var parameters = new SqlParameter[4];
                parameters[0] = new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_GET_EXCHANGE_RATE_COMPANY_ID), companyId);
                parameters[1] = new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_GET_EXCHANGE_RATE_FROM_CURRENCY), currencyIdBegining);
                parameters[2] = new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_GET_EXCHANGE_RATE_TO_CURRENCY), currencyIdDestiny);
                parameters[3] = new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_GET_EXCHANGE_RATE_ACTUAL_DATE), fechaActual);
                var dataHelper = new SqlDataHelper(appConfig.GetConnectionString(Constants.DB_CONN));
                SqlDataReader result = dataHelper.ExecuteStoredProcedure(spName, parameters);
                decimal res = 1;
                while (result.Read())
                {
                    res = (decimal) result[appConfig.GetProperty(Constants.SP_OUTPUT_GET_EXCHANGE_RATE_EXCHANGE_RATE)];
                }
                dataHelper.CloseReader();

                /*if (res != 1)
                    _cacheManager.Add(key, res);*/
                return res;
            }
            catch (Exception ex)
            {
                ExceptionHandlingManager.ManageException(ex, ExceptionHandlingManager.ExceptionPolicyType.DataLayer);
                return 0;
            }
        }

        /// <summary>
        /// Permite insertar una nueva moneda
        /// </summary>
        /// <param name="currencyName">Nombre de la moneda a insertar</param>
        /// <param name="currencyMnemonic">Mnemonico de la moneda a insertar</param>
        /// <returns>Si se logró efectuar correctamente</returns>
        public bool InsertCurrency(string currencyName, string currencyMnemonic)
        {
            try
            {
                AppConfigReader appConfig = AppConfigReader.GetInstance();
                string spName = appConfig.GetProperty(Constants.SP_NAME_INSERT_CURRENCY);
                var parameters = new SqlParameter[2];
                parameters[0] =
                    new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_INSERT_CURRENCY_CURRENCY_NAME),
                                     currencyName);
                parameters[1] =
                    new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_INSERT_CURRENCY_CURRENCY_MNEMONIC),
                                     currencyMnemonic);
                var dataHelper = new SqlDataHelper(appConfig.GetConnectionString(Constants.DB_CONN));
                return GetResult(dataHelper.ExecuteStoredProcedure(spName, parameters), dataHelper);
            }
            catch (Exception ex)
            {
                ExceptionHandlingManager.ManageException(ex, ExceptionHandlingManager.ExceptionPolicyType.DataLayer);
                return false;
            }
        }
        /// <summary>
        /// Permite cambiar la moneda a una cuenta
        /// </summary>
        /// <param name="accountId">identificador de la cuenta</param>
        /// <param name="currencyName">nombre de la moneda</param>
        /// <returns>Booleano si se cambia la moneda</returns>
        public bool ChangeAccountCurrency(int accountId, string currencyName)
        {
            try
            {
                AppConfigReader appConfig = AppConfigReader.GetInstance();
                string spName = appConfig.GetProperty(Constants.SP_NAME_CHANGE_ACCOUNT_CURRENCY);
                var parameters = new SqlParameter[2];
                parameters[0] =
                    new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_CHANGE_ACCOUNT_CURRENCY_ACCOUNT_ID),
                                        accountId);
                parameters[1] =
                    new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_CHANGE_ACCOUNT_CURRENCY_CURRENCY_NAME),
                                        currencyName);
                var dataHelper = new SqlDataHelper(appConfig.GetConnectionString(Constants.DB_CONN));
                return GetResult(dataHelper.ExecuteStoredProcedure(spName, parameters), dataHelper);
            }
            catch (Exception ex)
            {
                ExceptionHandlingManager.ManageException(ex, ExceptionHandlingManager.ExceptionPolicyType.DataLayer);
                return false;
            }
        }
        /// <summary>
        /// Para Cambiar informacion de la cuenta
        /// </summary>
        /// <param name="accountId">Identificador unico de la cuenta</param>
        /// <param name="accountName">Nombre de la cuenta nueva</param>
        /// <param name="foreignName">Nombre de la cuenta en extrangero</param>
        /// <param name="currencyName">Nombre de la moneda</param>
        /// <returns>Booleano indicando el estado de la insercion</returns>
        public bool ChangeAccountInformation(int accountId, string accountName, string foreignName, string currencyName)
        {
            try
            {
                AppConfigReader appConfig = AppConfigReader.GetInstance();
                string spName = appConfig.GetProperty(Constants.SP_NAME_CHANGE_ACCOUNT_INFORMATION);
                var parameters = new SqlParameter[4];
                parameters[0] =
                    new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_CHANGE_ACCOUNT_INFORMATION_ACCOUNT_ID),
                                        accountId);
                parameters[1] =
                    new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_CHANGE_ACCOUNT_INFORMATION_ACCOUNT_NAME),
                                        accountName);
                parameters[2] =
                    new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_CHANGE_ACCOUNT_INFORMATION_FOREIGN_NAME),
                                        foreignName);
                parameters[3] =
                    new SqlParameter(appConfig.GetProperty(Constants.SP_PARAM_CHANGE_ACCOUNT_INFORMATION_CURRENCY_NAME),
                                        currencyName);
                var dataHelper = new SqlDataHelper(appConfig.GetConnectionString(Constants.DB_CONN));
                return GetResult(dataHelper.ExecuteStoredProcedure(spName, parameters), dataHelper);
            }
            catch (Exception ex)
            {
                ExceptionHandlingManager.ManageException(ex, ExceptionHandlingManager.ExceptionPolicyType.DataLayer);
                return false;
            }
        }


        #region Protected / Private Methods

        /// <summary>
        /// Dice si el Stored Procedure fue efectuado correctamente o no
        /// </summary>
        /// <param name="result">ResultSet que indica si fue efectuado correctamente o no</param>
        /// <param name="helper">DataHelper con que la operación fue efectuada</param>
        /// <returns>Verdadero si el SP se ejecutó bien, de lo contrario falso</returns>
        private static bool GetResult(SqlDataReader result, SqlDataHelper helper)
        {
            result.Read();
            bool actionPerformed =
                Convert.ToInt32(
                    result[AppConfigReader.GetInstance().GetProperty(Constants.SP_OUTPUT_ACTION_PERFORMED_RESULT)]) == 0
                    ? false
                    : true;
            helper.CloseConnection();
            return actionPerformed;
        }

        #endregion

        #region Singleton

        /// <summary>
        /// Única instancia de esta clase
        /// </summary>
        private static AccountDataManager _instance;

        private AccountDataManager()
        {
            _cacheManager = new CacheManager();
        }

        /// <summary>
        /// Método para implementar el patrón de Singleton
        /// </summary>
        /// <returns>Instancia única de la clase</returns>
        public static AccountDataManager GetInstance()
        {
            if (_instance == null)
                _instance = new AccountDataManager();
            return _instance;
        }

        #endregion

    }
}